﻿using System.Net.WebSockets;
using System.Text;
using System.Text.Json;
using IMClient.Model.Message;

namespace IMClient.WebSocketService;

public class WebSocketConnection
{
    public static string? WebSocketUrl { get; set; }
    public static ClientWebSocket? WS { get; set; }

    private static bool _isReceivingMessages;

    public static event Action<BaseMessage>? OnMessageReceived;

    public static async Task ConnectWebSocket()
    {
        if (string.IsNullOrEmpty(WebSocketUrl))
            throw new InvalidOperationException("WebSocket URL is not set");
            
        WS = new ClientWebSocket();
        await WS.ConnectAsync(new Uri(WebSocketUrl), CancellationToken.None);
    }

    public static async Task SendMessage(BaseMessage message)
    {
        if (WS == null || WS.State != WebSocketState.Open)
            throw new InvalidOperationException("WebSocket connection is not initialized or is closed.");
        
        try
        {
            string messageJson = message.ToJson();
            var messageBytes = Encoding.UTF8.GetBytes(messageJson);
            await WS.SendAsync(new ArraySegment<byte>(messageBytes), WebSocketMessageType.Text, true, CancellationToken.None);
            Console.WriteLine($"Message sent: {messageJson}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error sending message: {ex.Message}");
            throw;
        }
    }

    public static async Task ReceiveMessage()
    {
        if (WS == null || WS.State != WebSocketState.Open)
            throw new InvalidOperationException("WebSocket connection is not initialized or is closed.");

        var buffer = new byte[1024 * 4];
        var receivedData = new List<byte>();

        try
        {
            while (WS.State == WebSocketState.Open)
            {
                var result = await WS.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                receivedData.AddRange(buffer.Take(result.Count));

                if (result.EndOfMessage)
                {
                    var messageJson = Encoding.UTF8.GetString(receivedData.ToArray());
                    receivedData.Clear();

                    try
                    {
                        var jsonDoc = JsonDocument.Parse(messageJson);
                        var root = jsonDoc.RootElement;

                        // 获取 MessageType 属性
                        var messageType = root.GetProperty("MessageType").GetString();

                        BaseMessage? message = null;

                        if (messageType == "CHAT")
                        {
                            // 获取 ChatType 属性
                            var chatType = root.GetProperty("ChatType").GetString();

                            message = chatType switch
                            {
                                "private" => JsonSerializer.Deserialize<ChatMessage>(messageJson),
                                "group" => JsonSerializer.Deserialize<GroupChatMessage>(messageJson),
                                _ => null
                            };
                        }
                        else if (messageType == "SYSTEM")
                        {
                            var systemType = root.GetProperty("SystemType").GetString();
                            if (systemType== "GroupAvatarUpdateNotification")
                            {
                                message = JsonSerializer.Deserialize<GroupAvatarUpdateNotification>(messageJson);
                            }
                            else if (systemType == "GroupNameUpdateNotification")
                            {
                                message = JsonSerializer.Deserialize<GroupNameUpdateNotification>(messageJson);
                            }
                            else
                            {
                                message = JsonSerializer.Deserialize<SystemMessage>(messageJson);
                            }
                            
                        }

                        if (message != null)
                        {
                            OnMessageReceived?.Invoke(message);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Error parsing message JSON: {ex.Message}");
                    }
                }

                if (result.MessageType == WebSocketMessageType.Close)
                {
                    Console.WriteLine("WebSocket connection closed by server.");
                    break;
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error in ReceiveMessage: {ex.Message}");
        }
    }


    public static void StartReceivingMessages()
    {
        if (!_isReceivingMessages)
        {
            _isReceivingMessages = true;
            Task.Run(async () =>
            {
                await ReceiveMessage();
            });
        }
    }
}